home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / lib / addr / ap_p2s.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-28  |  11.9 KB  |  489 lines

  1. #include "util.h"               /* from ../utildir */
  2. #include "conf.h"               /* from ../mmdf/h */
  3. #include "ch.h"
  4. #include "ap.h"
  5. #include "dm.h"
  6. #include "ll_log.h"
  7.  
  8. /*  Format one address from pointers to constitutents, in a tree
  9.  *
  10.  *  Returns:    pointer to string if successful or
  11.  *              NOTOK if error
  12.  *
  13.  *  SEK - using ap_p2s to output for ap_t2s has the general problem
  14.  *              of losing comments.   Perhaps ap_t2s should be
  15.  *              separate?
  16.  */
  17.  
  18. extern LLog *logptr;
  19. extern int ap_outtype;
  20. extern char *multcat();
  21. extern char *strdup();
  22. extern char *ap_dmflip();
  23. extern Domain *dm_v2route();
  24.  
  25. LOCFUN val2str();
  26.  
  27. char *
  28. ap_p2s (group, name, local, domain, route)
  29.     AP_ptr  group,             /* beginning of group name  */
  30.         name,              /* beginning of person name  */
  31.         local,             /* beginning of local-part */
  32.         domain,            /* basic domain reference */
  33.         route;             /* beginning of 733 forward routing */
  34. {
  35.     Dmn_route   dmnroute;
  36.     AP_ptr      lastptr;
  37.     char        *routp;         /* 822 -> 733 route string */
  38.     int         inperson,
  39.         ingroup;
  40.     register char *strp;        /* The string we are building */
  41.     register char *cp;
  42.     register AP_ptr curptr;
  43.     char *flipptr;
  44.     char *stripptr;
  45.     char tmpbuf [LINESIZE];
  46.     char *tmpdomain [DM_NFIELD];
  47.     int tmpcnt;
  48.     char buf[LINESIZE];         /* buf for dm_v2route                 */
  49.     char *drefptr;              /* pointer to string to be output     */
  50.  
  51. #ifdef DEBUG
  52.     ll_log (logptr, LLOGFTR, "ap_p2s()");
  53.  
  54.     if ((ap_outtype & AP_822) == AP_822)   /* AP_733 is implicit default */
  55.     ll_log (logptr, LLOGFTR, "AP_822 on");
  56.     ll_log (logptr, LLOGFTR, (ap_outtype & AP_BIG)
  57.     ? "AP_BIG on" : "AP_LITTLE on");
  58.     if ((ap_outtype & AP_NODOTS) == AP_NODOTS)  /* AP_DOTS is implicit def. */
  59.     ll_log (logptr, LLOGFTR, "AP_NODOTS on");
  60. #endif
  61.  
  62.     inperson = ingroup = FALSE;
  63.     strp = strdup("");
  64.     routp = strdup("");
  65.  
  66.     if (group != (AP_ptr) 0) {
  67. #ifdef DEBUG
  68.     ll_log (logptr, LLOGFTR, "ap_p2s:  group is '%s'", group -> ap_obvalue);
  69. #endif
  70.     for (curptr = group; curptr != (AP_ptr)0; curptr = curptr -> ap_chain)
  71.     {                             /* print munged addr                  */
  72.         switch (curptr -> ap_obtype) {
  73.         default:
  74.         case APV_NIL:
  75.             break;
  76.  
  77.         case APV_CMNT:        /* Output value as comment */
  78.             if (name != (AP_ptr) 0) {
  79.                     /* only output comments for pretty forms */
  80.             val2str (tmpbuf, curptr -> ap_obvalue, APV_CMNT);
  81.             cp = multcat(strp, (strp[0]?" ":""), "(",tmpbuf,")", (char *)0);
  82.             free (strp);
  83.             if(cp == (char *)0)
  84.                 return( (char *)NOTOK);
  85.             strp = cp;
  86.             }
  87.             continue;
  88.  
  89.         case APV_NGRP:
  90.             ingroup = TRUE;
  91.         case APV_GRUP:
  92.             val2str (tmpbuf, curptr -> ap_obvalue, APV_GRUP);
  93.             cp = multcat(strp, tmpbuf, (char *)0);
  94.             free (strp);
  95.             if(cp == (char *)0)
  96.             return( (char *)NOTOK);
  97.             strp = cp;
  98.             continue;
  99.         }
  100.         break;
  101.     }
  102.     if (ingroup) {
  103.         cp = multcat(strp, ": ", (char *)0);
  104.         free (strp);
  105.         if(cp == (char *)0)
  106.         return( (char *)NOTOK);
  107.         strp = cp;
  108.     }
  109.     }
  110.  
  111.     if (name != (AP_ptr) 0) {
  112. #ifdef DEBUG
  113.     ll_log (logptr, LLOGFTR, "ap_p2s:  name is '%s'", name -> ap_obvalue);
  114. #endif
  115.     for (curptr = name; curptr != (AP_ptr)0; curptr = curptr -> ap_chain)
  116.     {                         /* print munged addr                  */
  117.         switch (curptr -> ap_obtype) {
  118.         default:
  119.         case APV_NIL:
  120.             break;
  121.  
  122.         case APV_CMNT:        /* Output value as comment */
  123.             val2str (tmpbuf, curptr -> ap_obvalue, APV_CMNT);
  124.             cp = multcat(strp, (strp[0]?" " : ""), "(", tmpbuf, ")", (char *)0);
  125.             free (strp);
  126.             if(cp == (char *)0)
  127.             return( (char *)NOTOK);
  128.             strp = cp;
  129.             continue;
  130.  
  131.         case APV_NPER:
  132.             inperson = TRUE;
  133.         case APV_PRSN:
  134.             val2str (tmpbuf, curptr -> ap_obvalue, APV_PRSN);
  135.             cp = multcat(strp, tmpbuf, (char *)0);
  136.             free (strp);
  137.             if(cp == (char *)0)
  138.             return( (char *)NOTOK);
  139.             strp = cp;
  140.             continue;
  141.         }
  142.         break;
  143.     }
  144.     }
  145.  
  146.     if (inperson) {
  147.     cp = multcat(strp, " <", (char *)0);
  148.     free (strp);
  149.     if(cp == (char *)0)
  150.         return( (char *)NOTOK);
  151.     strp = cp;
  152.     }
  153.  
  154.     if (route != (AP_ptr) 0)      /* we have routing info */
  155.     {
  156. #ifdef DEBUG
  157.     ll_log (logptr, LLOGFTR, "ap_p2s:  route is '%s'", route -> ap_obvalue);
  158. #endif
  159.     for (lastptr = curptr = route; ; curptr = curptr -> ap_chain) {
  160.         if (curptr == (AP_ptr)0)    /* Grot Grot !!!!!!! */
  161.         goto defcase1;
  162.         switch (curptr -> ap_obtype) {
  163.         case APV_EPER:
  164.         continue;
  165.  
  166.         defcase1:;    /* YEUCH !! */
  167.         default:
  168.         case APV_NIL:
  169.             if ((ap_outtype & AP_822) == AP_822) {
  170.                     /* piece of cake */
  171.             cp = multcat(strp, ":", (char *)0);
  172.             free (strp);
  173.             if(cp == (char *)0)
  174.                 return( (char *)NOTOK);
  175.             strp = cp;
  176.             }
  177.             break;
  178.  
  179.         case APV_CMNT:        /* Output value as comment */
  180.             if (name != (AP_ptr) 0) {
  181.             val2str (tmpbuf, curptr -> ap_obvalue, APV_CMNT);
  182.             cp = multcat(strp, (strp[0]?" ":""), "(",tmpbuf,")", (char *)0);
  183.             free (strp);
  184.             if(cp == (char *)0)
  185.                 return( (char *)NOTOK);
  186.             strp = cp;
  187.             }
  188.             continue;
  189.  
  190.         case APV_DLIT:
  191.         case APV_DOMN:
  192.             val2str (tmpbuf, curptr -> ap_obvalue, curptr -> ap_obtype);
  193.             flipptr = stripptr = (char *) 0;
  194.             drefptr = tmpbuf;
  195.             if (((ap_outtype & AP_BIG) == AP_BIG) ||
  196.                (((ap_outtype & AP_NODOTS) == AP_NODOTS) &&
  197.                 (curptr == lastptr)) ) {
  198.                 /* check domain ref in either case */
  199.             Domain  *lrval = dm_v2route (tmpbuf, buf, &dmnroute);
  200.  
  201.             if(lrval == (Domain *)MAYBE)
  202.                 return( (char *)MAYBE);
  203.  
  204.             if (lrval != (Domain *) NOTOK) {
  205.                 if ((ap_outtype & AP_NODOTS) == AP_NODOTS
  206.                 && curptr == lastptr) {
  207.                 /* only strip domain on next-hop in route */
  208.                 tmpcnt = cstr2arg (dmnroute.dm_argv[0],
  209.                     DM_NFIELD, tmpdomain, '.');
  210.                 stripptr = strdup(tmpdomain[0]);
  211.                 drefptr = stripptr;
  212.                 } 
  213.                 else 
  214.                 if ((ap_outtype & AP_BIG) == AP_BIG) {
  215.                     flipptr = ap_dmflip (buf);
  216.                     drefptr = flipptr;
  217.                 }
  218.             }
  219.             }
  220.  
  221.             if ((ap_outtype & AP_822) == AP_822) {
  222.                     /* piece of cake */
  223.                 cp = multcat(strp,(curptr!=lastptr?",@":"@"),drefptr,(char *)0);
  224.             free (strp);
  225.             if(cp == (char *)0)
  226.                 return( (char *)NOTOK);
  227.             strp = cp;
  228.             } else {
  229.             if(routp[0] == '\0')
  230.                 cp = multcat("@", drefptr, (char *)0);
  231.             else
  232.                 cp = multcat("%", drefptr, routp, (char *)0);
  233.             free (routp);
  234.             if(cp == (char *)0)
  235.                 return( (char *)NOTOK);
  236.             routp = cp;
  237.             }
  238.             if (flipptr != (char *)0)
  239.             free (flipptr);
  240.             if (stripptr != (char *)0)
  241.             free (stripptr);
  242.             continue;
  243.         }
  244.         break;
  245.     }
  246.     }
  247.  
  248.     if (local != (AP_ptr) 0) {
  249. #ifdef DEBUG
  250.     ll_log (logptr, LLOGFTR, "ap_p2s:  local is '%s'", local -> ap_obvalue);
  251. #endif
  252.     for (curptr = local; curptr != (AP_ptr)0; curptr = curptr -> ap_chain) {
  253.         switch (curptr -> ap_obtype) {        /* print munged addr */
  254.         default:
  255.         case APV_NIL:
  256.             break;
  257.  
  258.         case APV_CMNT:        /* SEK - don't skip these */
  259.             if (name != (AP_ptr) 0) {
  260.             val2str (tmpbuf, curptr -> ap_obvalue, APV_CMNT);
  261.             cp = multcat(strp, (strp[0]?" ":""), "(",tmpbuf,")", (char *)0);
  262.             free (strp);
  263.             if(cp == (char *)0)
  264.                 return( (char *)NOTOK);
  265.             strp = cp;
  266.             }
  267.             continue;
  268.  
  269.         case APV_WORD:
  270.         case APV_MBOX:
  271.                     /* SEK - YUK                    */
  272.             if (strindex (":Include:", curptr -> ap_obvalue) == 0)
  273.             (void) strcpy (tmpbuf, curptr -> ap_obvalue);
  274.             else
  275.             val2str (tmpbuf, curptr -> ap_obvalue, APV_MBOX);
  276.             cp = multcat(strp, tmpbuf, (char *)0);
  277.             free (strp);
  278.             if(cp == (char *)0)
  279.             return( (char *)NOTOK);
  280.             strp = cp;
  281.             continue;
  282.         }
  283.         break;
  284.     }
  285.     }
  286.  
  287.     if (domain != (AP_ptr) 0) {
  288. #ifdef DEBUG
  289.     ll_log (logptr, LLOGFTR, "ap_p2s:  domain is '%s'",
  290.         domain -> ap_obvalue);
  291. #endif
  292.     val2str (tmpbuf, domain -> ap_obvalue, domain -> ap_obtype);
  293.     flipptr = stripptr = (char *) 0;
  294.     drefptr = tmpbuf;
  295.     if (((ap_outtype & AP_BIG) == AP_BIG) ||
  296.        (((ap_outtype & AP_NODOTS) == AP_NODOTS)) && route == (AP_ptr) 0) {
  297.         /* check domain ref in either case */
  298.         Domain  *lrval = dm_v2route (tmpbuf, buf, &dmnroute);
  299.  
  300.         if(lrval == (Domain *)MAYBE)
  301.         return( (char *)MAYBE);
  302.  
  303.         if (lrval != (Domain *) NOTOK) {
  304.         if (((ap_outtype & AP_NODOTS) == AP_NODOTS) &&
  305.             (route == (AP_ptr) 0)) {
  306.             /* If there is no route, this domain is next hop: strip */
  307.             tmpcnt = cstr2arg (dmnroute.dm_argv[0], DM_NFIELD, 
  308.                     tmpdomain, '.');
  309.             stripptr = strdup(tmpdomain[0]);
  310.             drefptr = stripptr;
  311.         }
  312.         else
  313.             if ((ap_outtype & AP_BIG) == AP_BIG) {
  314.             flipptr = ap_dmflip (buf);
  315.             drefptr = flipptr;
  316.             }
  317.         }
  318.     }
  319.  
  320.     if ((ap_outtype & AP_822) == AP_822 || routp[0] == '\0')  /* easy */
  321.         cp = multcat (strp, "@", drefptr, routp, (char *)0);
  322.     else
  323.         cp = multcat (strp, "%", drefptr, routp, (char *)0);
  324.  
  325.     if(cp == (char *)0)
  326.         return(cp);
  327.     free (strp);
  328.     strp = cp;
  329.     if (flipptr != (char *) 0)
  330.         free (flipptr);
  331.     if (stripptr != (char *) 0)
  332.         free (stripptr);
  333.     }
  334.     free (routp);
  335.  
  336.     if (inperson) {
  337.     cp = multcat(strp, ">", (char *)0);
  338.     free (strp);
  339.     if(cp == (char *)0)
  340.         return( (char *)NOTOK);
  341.     strp = cp;
  342.     }
  343.     if (ingroup) {
  344.     cp = multcat(strp, ";", (char *)0);
  345.     free (strp);
  346.     if (cp == (char *)0)
  347.             return( (char *)NOTOK);
  348.     strp = cp;
  349.     }
  350.     return (strp);
  351. }
  352.  
  353.  
  354. /*
  355.  *  This function is just barely usable.  The hole problem of
  356.  *  quoted strings is hard to get right especially when the
  357.  *  mail system is trying to make up for human forgetfulness.
  358.  *                              -DPK-
  359.  *  SEK - have improved this somewhat by giving knowledge of
  360.  *  the various object types.  Does not handle strings of spaces.
  361.  */
  362. LOCFUN
  363.     val2str (buf, value, obtype)      /* convert to canonical string */
  364.     char *buf,
  365.      *value,
  366.      obtype;
  367. {
  368.     int gotspcl;
  369.     int inquote;
  370.     register char *fromptr,
  371.           *toptr;
  372. #ifdef DEBUG
  373.     ll_log (logptr, LLOGFTR, "val2str ('%s', %d)", value, obtype);
  374. #endif
  375.  
  376.  
  377.     if (obtype == APV_CMNT) {
  378.     for (fromptr=value, toptr=buf; *fromptr != '\0'; *toptr++ = *fromptr++)
  379.         switch (*fromptr) {
  380.         case '\r':
  381.         case '\n':
  382.         case '\\':
  383.         case '(':
  384.         case ')':
  385.             *toptr++ = '\\';
  386.         }
  387.     *toptr = '\0';
  388.     return;
  389.     }
  390.  
  391.     if (obtype == APV_DLIT) {
  392.     for (fromptr=value, toptr=buf; *fromptr != '\0'; *toptr++ = *fromptr++)
  393.         switch (*fromptr) {
  394.         case '\r':
  395.         case '\n':
  396.         case '\\':
  397.             *toptr++ = '\\';
  398.             continue;
  399.         case '[':
  400.             if (fromptr != value)
  401.                *toptr++ = '\\';
  402.             continue;
  403.         case ']':
  404.             if (*(fromptr + 1) != (char) 0)
  405.             *toptr++ = '\\';
  406.         }
  407.     *toptr = '\0';
  408.     return;
  409.     }
  410.  
  411.     inquote = FALSE;
  412.     for (gotspcl = FALSE, fromptr = value; *fromptr != '\0'; fromptr++) {
  413.     switch (*fromptr) {
  414.         case '"':
  415.         inquote = (inquote == TRUE ? FALSE : TRUE);     /* Flip-Flop */
  416.         break;
  417.  
  418.         case '\\':
  419.         case '\r':
  420.         case '\n':
  421.         if (inquote == FALSE) {
  422.             gotspcl = TRUE;
  423.             goto copyit;
  424.         }
  425.         break;
  426.  
  427.         case '<':
  428.         case '>':
  429.         case '@':
  430.         case ',':
  431.         case ';':
  432.         case ':':
  433.         case '\t':
  434.         case '[':
  435.         case ']':
  436.         case '(':
  437.         case ')':
  438.         if( inquote == FALSE) {
  439.             gotspcl = TRUE;
  440.             goto copyit;
  441.         }
  442.         break;
  443.  
  444.         case ' ':
  445.         if (inquote == FALSE)
  446.             if ((obtype == APV_DOMN) || (obtype == APV_MBOX)) {
  447.             gotspcl = TRUE;
  448.             goto copyit;
  449.             } else {
  450.                 /* SEK hack to handle " at "              */
  451.                 /* yes - this really is needed          */
  452.             if ((uptolow(*(fromptr + 1)) == 'a') &&
  453.                 (uptolow(*(fromptr + 2)) == 't') &&
  454.                 (*(fromptr + 3) == ' ')) {
  455.                 gotspcl = TRUE;
  456.                 goto copyit;
  457.             }
  458.             }
  459.         break;
  460.  
  461.         case '.':
  462.         if (inquote == FALSE && ((obtype == APV_GRUP) || (obtype == APV_PRSN)))
  463.         {
  464.             gotspcl = TRUE;
  465.             goto copyit;
  466.         }
  467.         break;
  468.     }
  469.     }
  470.  
  471.     gotspcl = inquote;          /* If were in a quote, something's wrong */
  472. copyit:
  473.     toptr = buf;
  474.     if (gotspcl)
  475.     *toptr++ = '"';
  476.     for (fromptr = value; *fromptr != '\0'; *toptr++ = *fromptr++)
  477.     switch (*fromptr) {
  478.         case '\r':
  479.         case '\n':
  480.         case '\\':
  481.         case '"':
  482.         if (gotspcl)
  483.             *toptr++ = '\\';
  484.     }
  485.     if (gotspcl)
  486.     *toptr++ = '"';
  487.     *toptr = '\0';
  488. }
  489.